package lib.base.ext

import android.animation.Animator
import android.animation.ValueAnimator
import android.text.Spanned
import android.text.style.ClickableSpan
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.view.forEachIndexed
import com.blankj.utilcode.util.ClickUtils
import timber.log.Timber

/**
 *  author: luoXiong
 *  e-mail: 382060748@qq.com
 *  date: 2020/6/5 08:33
 *  version: 1.0
 *  desc: View 相关操作
 */


/**
 * 获取指定位置的View
 */
fun View?.getSpecChildAt(index: Int): View? {
    if (this is ViewGroup) {
        return this.getChildAt(index)
    }
    return null
}

// 防抖动, 默认过滤500毫秒内的点击次数
fun View?.clickDebouncing(delayMillis: Long = 400, clickListener: () -> Unit) {
    this ?: return
    ClickUtils.applySingleDebouncing(this,delayMillis) { clickListener.invoke() }
}
/**
 * 设置长按监听
 */
fun View.longClick(action: (view: View) -> Boolean) {
    if (this is TextView) setOnTouchListener(FixClickSpanTouchListener())
    setOnLongClickListener {
        action(it)
    }
}

/**
 * 设置View的高度
 */
fun View?.height(height: Int): View? {
    this ?: return null
    val params = layoutParams ?: ViewGroup.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.WRAP_CONTENT
    )
    params.height = height
    layoutParams = params
    return this
}

/**
 * 设置View的宽度
 */
fun View.width(width: Int): View {
    val params = layoutParams ?: ViewGroup.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.WRAP_CONTENT
    )
    params.width = width
    layoutParams = params
    return this
}


/**
 * 设置View的margin
 * @param leftMargin 默认保留原来的
 * @param topMargin 默认是保留原来的
 * @param rightMargin 默认是保留原来的
 * @param bottomMargin 默认是保留原来的
 */
fun View.margin(
    leftMargin: Int = Int.MAX_VALUE,
    topMargin: Int = Int.MAX_VALUE,
    rightMargin: Int = Int.MAX_VALUE,
    bottomMargin: Int = Int.MAX_VALUE
): View {
    val params = layoutParams as ViewGroup.MarginLayoutParams
    if (leftMargin != Int.MAX_VALUE)
        params.leftMargin = leftMargin
    if (topMargin != Int.MAX_VALUE)
        params.topMargin = topMargin
    if (rightMargin != Int.MAX_VALUE)
        params.rightMargin = rightMargin
    if (bottomMargin != Int.MAX_VALUE)
        params.bottomMargin = bottomMargin
    layoutParams = params
    return this
}

/**
 * 设置宽度，带有过渡动画
 * @param targetValue 目标宽度
 * @param duration 时长
 * @param action 可选行为
 */
fun View.animateWidth(
    targetValue: Int, duration: Long = 400, listener: Animator.AnimatorListener? = null,
    action: ((Float) -> Unit)? = null
) {
    post {
        ValueAnimator.ofInt(width, targetValue).apply {
            addUpdateListener {
                width(it.animatedValue as Int)
                action?.invoke((it.animatedFraction))
            }
            if (listener != null) addListener(listener)
            setDuration(duration)
            start()
        }
    }
}

/**
 * 设置高度，带有过渡动画
 * @param targetValue 目标高度
 * @param duration 时长
 * @param action 可选行为
 */
fun View.animateHeight(
    targetValue: Int,
    duration: Long = 400,
    listener: Animator.AnimatorListener? = null,
    action: ((Float) -> Unit)? = null
) {
    post {
        ValueAnimator.ofInt(height, targetValue).apply {
            addUpdateListener {
                height(it.animatedValue as Int)
                action?.invoke((it.animatedFraction))
            }
            if (listener != null) addListener(listener)
            setDuration(duration)
            start()
        }
    }
}

fun View?.gone(): View? {
    this ?: return null
    if (this.visibility != View.GONE) {
        this.visibility = View.GONE
    }
    return this
}

fun View?.invisible(): View? {
    this ?: return null
    if (this.visibility != View.INVISIBLE) {
        this.visibility = View.INVISIBLE
    }
    return this
}

fun View?.visible(): View? {
    this ?: return this
    if (this.visibility != View.VISIBLE) {
        this.visibility = View.VISIBLE
    }
    return this
}
class FixClickSpanTouchListener : View.OnTouchListener {
    private var mLastActionDownTime: Long = -1
    override fun onTouch(v: View, event: MotionEvent): Boolean {
        val action = event.action
        if(v is TextView){
            val text = v.text
            if (action == MotionEvent.ACTION_DOWN) {
                mLastActionDownTime = System.currentTimeMillis()
            } else {
                val actionUpTime = System.currentTimeMillis()
                if (mLastActionDownTime!=-1L && actionUpTime - mLastActionDownTime >= ViewConfiguration.getLongPressTimeout() ) {
                    mLastActionDownTime = -1
                    return v.performLongClick()
                }
                if (action == MotionEvent.ACTION_UP) {
                    if (text is Spanned) {
                        var x = event.x.toInt()
                        var y = event.y.toInt()
                        x -= v.totalPaddingLeft
                        y -= v.totalPaddingTop
                        x += v.scrollX
                        y += v.scrollY
                        val layout = v.layout
                        val line = layout.getLineForVertical(y)
                        val off = layout.getOffsetForHorizontal(line, x.toFloat())
                        val link = text.getSpans(off, off, ClickableSpan::class.java)
                        if (link!=null && link.isNotEmpty()) {
                            link[0].onClick(v)
                        } else {
                            v.performClick()
                        }
                    } else {
                        v.performClick()
                    }
                }
            }
            return true
        }
        return false
    }
}

/**
 * 获取当前View在父View中的位置
 */
//fun View?.getChildAtInParent(): Int {
//    if (this?.parent is ViewGroup) {
//        (this.parent as ViewGroup).forEachIndexed { i, view ->
//            if (this == view) {
//                return i
//            }
//        }
//    }
//    return -1
//}